package myJs.user

import java.math.BigInteger

import scala.scalajs.js
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}
import myJs.Utils._
import myJs.myPkg._
import org.scalajs.dom.Element
import org.scalajs.dom
import org.scalajs.dom._
import org.w3c.dom.html.HTMLSelectElement
import scalatags.Text.all.{value, _}

import scala.scalajs.js.JSConverters._

import myJs.tool.Tool._
import org.scalajs.dom.raw.HTMLFormElement

import scala.scalajs.js.JSON
import myJs.myPkg.jquery._
import myJs.myPkg.bootstrap.Bootstrap.default._
import myJs.myPkg.ztree.Ztree
import org.scalajs.dom.ext.Ajax

import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.Try
import myJs.Implicits._
import myJs.tool.Tool
import scala.scalajs.js.Dynamic.{global => g}

/**
 * Created by yz on 2019/4/25
 */
@JSExportTopLevel("NewMission")
object NewMission {

  val url = g.jsRoutes.controllers.MissionController.getChildrenNodes().url.toString

  val setting = js.Dictionary(
    "view" -> js.Dictionary(
      "expandSpeed" -> ""
    ),
    "async" -> js.Dictionary(
      "enable" -> true,
      "url" -> url,
      "autoParam" -> js.Array("id"),
    ),
    "data" -> js.Dictionary(
      "simpleData" -> js.Dictionary(
        "enable" -> true
      )
    ),
    "callback" -> js.Dictionary(
      "onClick" -> onClick,
      "beforeExpand" -> beforeExpand,
    ),
  )

  val batchFormId = "batchForm"
  val treeId = "treeDemo"

  @JSExport("init")
  def init = {

    bootStrapValidator
    g.$("#form").bootstrapValidator("revalidateField", "missionName")

    batchFormBootStrapValidator
    g.$("#batchForm").bootstrapValidator("revalidateField", "missionName")

    initWidth

  }

  @JSExport("confirmSelect")
  def confirmSelect = {
    val treeId = "treeDemo"
    val zTree = Ztree.getZTreeObj(treeId)
    val nodes = zTree.getSelectedNodes()
    val v = nodes.map(_ ("id")).mkString(",")
    $("#citySel").`val`(v)
    hideMenu
  }

  def initWidth = {
    val cityObj = $("#citySel").parent()
    val width = cityObj.css("width").toString.replaceAll("px$", "").toDouble
    $(s"#menuContent").css("width", s"${width}px")
  }

  def onClick: js.Function = (e: Event, treeId: String, treeNode: js.Any) => {
    val zTree = Ztree.getZTreeObj(treeId)
    val nodes = zTree.getSelectedNodes()
    val v = nodes.map(_ ("id")).mkString(",")
    $("#citySel").`val`(v)
    refreshFileTree(v)
    $(s"#${batchFormId}").bv.revalidateField( "splitDir")
  }

  def refreshFileTree(dir: String) = {
    val setting = js.Dictionary(
      "view" -> js.Dictionary(
        "expandSpeed" -> ""
      ),
      "data" -> js.Dictionary(
        "simpleData" -> js.Dictionary(
          "enable" -> true
        )
      ),
      "callback" -> js.Dictionary(
        "beforeExpand" -> beforeExpand,
      ),
    )
    val url = g.jsRoutes.controllers.MissionController.getFiles().url.toString
    Ajax.get(url = s"${url}?splitDir=${dir}", headers = Map("Content-Type" -> "application/json")).map { xhr =>
      val data = xhr.responseText.toJArJDS
      val treeId = "fileTree"
      Ztree.init($(s"#${treeId}"), setting, data)
    }
  }

  def beforeExpand: js.Function = (treeId: String, treeNode: js.Dictionary[String]) => {
    ajaxGetNodes(treeNode, "refresh")
    true
  }

  def ajaxGetNodes(treeNode: js.Dictionary[String], reloadType: String) = {
    val zTree = Ztree.getZTreeObj("treeDemo")
    if (reloadType == "refresh") {
      zTree.updateNode(treeNode)
    }
    zTree.reAsyncChildNodes(treeNode, reloadType, true)
  }

  @JSExport("myRun")
  def myRun = {
    val bv = jQuery("#form").data("bootstrapValidator")
    bv.validate()
    val valid = bv.isValid().toB
    if (valid) {
      val formData = new FormData(document.getElementById("form").toHTMLFormElement)
      $(":disabled").attr("disabled", false)
      val element = div(id := "content",
        span(id := "info", "正在分析",
          span(id := "progress", "。。。")), " ",
        img(src := "/assets/images/running2.gif", cls := "runningImage", width := 30, height := 20)
      ).render
      val layerOptions = LayerOptions.title(zhInfo).closeBtn(0).skin("layui-layer-molv").btn(js.Array())
      val index = layer.alert(element, layerOptions)
      val url = g.jsRoutes.controllers.MissionController.newMission().url.toString
      val xhr = new XMLHttpRequest
      xhr.open("post", url)
      xhr.upload.onprogress = progressHandlingFunction
      xhr.onreadystatechange = (e) => {
        if (xhr.readyState == XMLHttpRequest.DONE) {
          val data = xhr.response
          val rs = JSON.parse(data.toString).toJDJAn
          layer.close(index)
          val valid = rs("valid").toB
          if (valid) {
            window.location.href = g.jsRoutes.controllers.UserController.missionManageBefore().url.toString
          } else {
            g.swal("Error", rs.myGet("message"), "error")
          }
        }
      }
      xhr.send(formData)
    }
  }

  @JSExport("onBodyDown")
  def onBodyDown = (y: Element, e: Event) => {
    val targetElem = e.target.toElement
    val b = targetElem.id == "menuBtn" || targetElem.id == "menuContent" ||
      $(targetElem).parents("#menuContent").length > 0
    if (!b) {
      hideMenu
    }
  }

  @JSExport("hideMenu")
  def hideMenu: JQuery = {
    $("#menuContent").fadeOut("fast")
    $("body").unbind("mousedown", onBodyDown)
  }

  def getTreeNodes = {
    val splitDir = Tool.getInputByName("splitDir").`val`().toString
    val url = g.jsRoutes.controllers.MissionController.getTreeNodes().url.toString
    val formData = new FormData(document.getElementById("batchForm").toHTMLFormElement)
    Ajax.post(url = s"${url}", data = formData).map { xhr =>
      xhr.responseText
    }
  }

  @JSExport("cancel")
  def cancel = {
    $("#citySel").`val`("")
    $("#batchForm").bv.revalidateField("splitDir")
    hideMenu

  }

  def selectNode = {
    val treeObj = Ztree.getZTreeObj("treeDemo")
    val nodes = treeObj.transformToArray(treeObj.getNodes())
    val gzPath = $(":input[name='splitDir']").`val`()
    val nodeOp = nodes.filter(_ ("id") == gzPath).headOption
    nodeOp match {
      case Some(node) =>
        treeObj.selectNode(node)
      case None =>
        treeObj.cancelSelectedNode()
    }
  }

  @JSExport("showMenu")
  def showMenu = {
    val cityObj = $("#citySel")
    val cityOffset = $("#citySel").offset()
    val parentLeft = $("#parentPanel").offset().left
    val left = cityOffset.left - parentLeft + 15
    val top = cityOffset.top + cityObj.outerHeight() - 135
    $("#menuContent").css("left", s"${left}px").css("top", s"${top}px").
      slideDown("fast")
    $("body").bind("mousedown", onBodyDown)
    getTreeNodes.foreach { data =>
      val jsons = JSON.parse(data).toJArJDS
      Ztree.init($("#treeDemo"), setting, jsons)
      selectNode
      val splitDir = Tool.getInputByName("splitDir").`val`().toString
      refreshFileTree(splitDir)
    }

  }

  @JSExport("batchRun")
  def batchRun = {
    val formId = "batchForm"
    val bv = jQuery(s"#${formId}").data("bootstrapValidator")
    bv.validate()
    val valid = bv.isValid().toB
    if (valid) {
      val formData = new FormData(document.getElementById(formId).toHTMLFormElement)
      $(":disabled").attr("disabled", false)
      val element = div(id := "content",
        span(id := "info", "正在运行",
          span(id := "progress", "。。。")), " ",
        img(src := "/assets/images/running2.gif", cls := "runningImage", width := 30, height := 20)
      ).render
      val layerOptions = LayerOptions.title(zhInfo).closeBtn(0).skin("layui-layer-molv").btn(js.Array())
      val index = layer.alert(element, layerOptions)
      val url = g.jsRoutes.controllers.MissionController.newBatchMission().url.toString
      val xhr = new XMLHttpRequest
      xhr.open("post", url)
      xhr.upload.onprogress = progressHandlingFunction
      xhr.onreadystatechange = (e) => {
        if (xhr.readyState == XMLHttpRequest.DONE) {
          val data = xhr.response
          val rs = JSON.parse(data.toString).toJDJAn
          val valid = rs("valid").toB
          if (valid) {
            layer.close(index)
            window.location.href = g.jsRoutes.controllers.UserController.missionManageBefore().url.toString
          } else {
            layer.close(index)
            val dict = Try(JSON.parse(rs.myGet("message")).toJDS).toOption match {
              case Some(value) => value
              case None => js.Dictionary("valid" -> "false")
            }
            if (dict.isDefinedAt("confirm")) {
              val confirmOptions = LayerOptions.btn(js.Array("覆盖", "取消"))
              layer.confirm(dict("message"), confirmOptions, (confirmIndex: Int) => {
                confirmRun(true, confirmIndex)
              }, () => (
                clearFile
                ))
            } else {
              clearFile
              g.swal("Error", rs.myGet("message"), "error")
            }
          }
        }
      }
      xhr.send(formData)
    }
  }

  def confirmRun(isCover: Boolean, confirmIndex: Int) = {
    val formId = "batchForm"
    val formData = new FormData(document.getElementById(formId).toHTMLFormElement)
    formData.append("isCover", isCover)
    $(":disabled").attr("disabled", false)
    val url = g.jsRoutes.controllers.MissionController.newBatchMission().url.toString
    val xhr = new XMLHttpRequest
    xhr.open("post", url)
    xhr.upload.onprogress = progressHandlingFunction
    xhr.onreadystatechange = (e) => {
      if (xhr.readyState == XMLHttpRequest.DONE) {
        val data = xhr.response
        val rs = JSON.parse(data.toString).toJDJAn
        val valid = rs("valid").toB
        if (valid) {
          layer.close(confirmIndex)
          window.location.href = g.jsRoutes.controllers.UserController.missionManageBefore().url.toString
        } else {
          clearFile
          val dict = JSON.parse(rs.myGet("message")).toJDS
          g.swal("Error", rs.myGet("message"), "error")
        }
      }
    }
    xhr.send(formData)
  }

  def clearFile = {
    $(":input[name='sampleInfoFile']").fileinput("clear")
    $(s"#${batchFormId}").bv.revalidateField("sampleInfoFile")
  }

  def bootStrapValidator = {
    val url = g.jsRoutes.controllers.MissionController.missionNameCheck().url.toString
    val maxNumber = Double.MaxValue
    val dict = js.Dictionary(
      "feedbackIcons" -> js.Dictionary(
        "valid" -> "glyphicon glyphicon-ok",
        "invalid" -> "glyphicon glyphicon-remove",
        "validating" -> "glyphicon glyphicon-refresh",
      ),
      "fields" -> js.Dictionary(
        "missionName" -> js.Dictionary(
          "validators" -> js.Dictionary(
            "notEmpty" -> js.Dictionary(
              "message" -> "分析名称不能为空!"
            ),
            "remote" -> js.Dictionary(
              "message" -> "分析名称已存在!",
              "extension" -> "csv",
              "url" -> url,
              "type" -> "POST",
              "delay" -> 1000
            ),
          )
        ),
        "id" -> js.Dictionary(
          "validators" -> js.Dictionary(
            "notEmpty" -> js.Dictionary(
              "message" -> "id不能为空!"
            ),
          )
        ),
        "fqFile" -> js.Dictionary(
          "validators" -> js.Dictionary(
            "notEmpty" -> js.Dictionary(
              "message" -> "fq文件不能为空!"
            ),
            "file" -> js.Dictionary(
              "message" -> "fq文件格式不正确!",
              "extension" -> "txt",
            ),
          )
        ),

      )
    )
    g.$("#form").bootstrapValidator(dict)

  }

  def batchFormBootStrapValidator = {
    val url = g.jsRoutes.controllers.MissionController.missionNameCheck().url.toString
    val maxNumber = Double.MaxValue
    val dict = js.Dictionary(
      "feedbackIcons" -> js.Dictionary(
        "valid" -> "glyphicon glyphicon-ok",
        "invalid" -> "glyphicon glyphicon-remove",
        "validating" -> "glyphicon glyphicon-refresh",
      ),
      "fields" -> js.Dictionary(
        "missionName" -> js.Dictionary(
          "validators" -> js.Dictionary(
            "notEmpty" -> js.Dictionary(
              "message" -> "分析名称不能为空!"
            ),
            "remote" -> js.Dictionary(
              "message" -> "分析名称已存在!",
              "extension" -> "csv",
              "url" -> url,
              "type" -> "POST",
              "delay" -> 1000
            ),
          )
        ),
        "gzFile" -> js.Dictionary(
          "validators" -> js.Dictionary(
            "notEmpty" -> js.Dictionary(
              "message" -> "gz文件不能为空!"
            ),
            "file" -> js.Dictionary(
              "message" -> "gz文件格式不正确!",
              "extension" -> "gz",
            ),
          )
        ),
        "splitDir" -> js.Dictionary(
          "validators" -> js.Dictionary(
            "notEmpty" -> js.Dictionary(
              "message" -> "目录不能为空!"
            ),
          )
        ),
        "serverGzFile" -> js.Dictionary(
          "validators" -> js.Dictionary(
            "notEmpty" -> js.Dictionary(
              "message" -> "gz文件不能为空!"
            ),
          )
        ),
        "indexFile" -> js.Dictionary(
          "validators" -> js.Dictionary(
            "notEmpty" -> js.Dictionary(
              "message" -> "index文件不能为空!"
            ),
            "file" -> js.Dictionary(
              "message" -> "index文件格式不正确!",
              "extension" -> "txt",
            ),
          )
        ),
        "sampleInfoFile" -> js.Dictionary(
          "validators" -> js.Dictionary(
            "notEmpty" -> js.Dictionary(
              "message" -> "样品信息文件不能为空!"
            ),
            "file" -> js.Dictionary(
              "message" -> "样品信息文件格式不正确!",
              "extension" -> "xlsx",
            ),
          )
        ),

      )
    )
    g.$("#batchForm").bootstrapValidator(dict)

  }

}
